/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using System.Text;
using System.Text.RegularExpressions;
using Unicode = System.Qizx.Util.Basic.Unicode;
using Utils = System.Qizx.Util.Basic.Utils;
using Matcher = System.Text.RegularExpressions.Regex;

namespace System.Qizx.Util
{

    /// <summary> A String Pattern based on regular expressions. 
    /// Trick: define this as StringBuilder to use the Matcher several times
    /// Caution: for reuse of matcher
    /// </summary>
    public class RegexMatchPattern : StringPattern
    {
        virtual public bool DiacriticsSensitive
        {
            get
            {
                return _diacriticsSensitive;
            }

            set
            {
                this._diacriticsSensitive = value;
            }

        }
        protected internal Pattern matcher;
        protected internal char[] _toMatch;
        protected internal bool _diacriticsSensitive = true;

        public RegexMatchPattern(Pattern pattern)
            : base(null, 0)
        {
            matcher = pattern.matcher(this);
            // fixed prefix:
            string pat = pattern.pattern();
            int reject = 0, size = pat.Length;
            for (; reject < size; reject++)
            {
                char c = pat[reject];
                if (".\\[{*+?".IndexOf((System.Char)c) >= 0)
                    // OPTIM
                    break;
            }
            _fixedPrefix = Utils.subArray(pat.ToCharArray(), 0, reject);
            _fixedPrefixStart = reject;
            _caseSensitive = (pattern.flags() & Pattern.CASE_INSENSITIVE) == 0;
        }

        public override bool matches(char[] text)
        {
            _toMatch = text;
            return matcher.IsMatch(new string(_toMatch));
        }

        public override int match(char[] string_Renamed)
        {
            // compare fixed prefix: used to determine if beyond 
            int cmp = Utils.prefixCompare(_fixedPrefix, string_Renamed, _fixedPrefix.Length, _caseSensitive, _diacriticsSensitive);
            if (cmp != 0)
                return (cmp < 0) ? BEYOND : NOMATCH;
            // normal matching:
            return matches(string_Renamed) ? MATCH : NOMATCH; // OPTIM
        }

        public virtual char charAt(int index)
        {
            return _diacriticsSensitive ? _toMatch[index] : Unicode.collapseDiacritic(_toMatch[index]);
        }

        public virtual int length()
        {
            return _toMatch == null ? 0 : _toMatch.Length;
        }

        public virtual StringBuilder subSequence(int start, int end)
        {
            return null; // not used;
        }

        public override string ToString()
        {
            return "Regexp TODO 1";//.pattern();
        }
    }
}